package com.szholly.plug.activity.core;

import org.apache.log4j.Logger;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.DefaultTransactionDefinition;

import com.szholly.utils.spring.SpringBeanFactory;

/**
 * 获取配置中的工作流事务管理器
 */
public class BpmTransactionManager {
	
	private static Logger logger = Logger.getLogger(BpmTransactionManager.class);
	
	// 单一实例
	public static final BpmTransactionManager singleRef = new BpmTransactionManager();
	
	/**
	 * 当前的事务处理状态
	 */
	private ThreadLocal<TransactionStatus> transactionStatus = new ThreadLocal<TransactionStatus>();
	/**
	 * 事务层数
	 */
	private ThreadLocal<Integer> transactionRegs = new ThreadLocal<Integer>();

	/**
	 * 在事务块中是否调用过Rollback
	 */
	private ThreadLocal<Boolean> hasInvokeRollback = new ThreadLocal<Boolean>();
	
	private BpmTransactionManager(){
		
	}
	
	/**
	 * 开始一个事务
	 */
	public void StartTransactions() {
		TransactionStatus status = transactionStatus.get();
		if (status == null) {
			// 开始一个事务
			DefaultTransactionDefinition definition = new DefaultTransactionDefinition();
			definition.setTimeout(30);
			status = getBpmTransaction().getTransaction(definition);
			transactionStatus.set(status);
			transactionRegs.set(1);
			hasInvokeRollback.set(false);
			String tranName = "[" + this.hashCode() + "_"
					+ Thread.currentThread().getId() + "]";
			logger.info("工作流事务StartTransactions 事务" + tranName + "开始");
		} else {
			// 说明上级存在注册的事务块，当前块不启做用
			Integer curInteger = transactionRegs.get();
			curInteger++;
			transactionRegs.set(curInteger);
		}
	}

	/**
	 * 停止一个事务
	 */
	public void StopTransactions(boolean saveEdits) {
		// 不存在事务
		TransactionStatus status = transactionStatus.get();
		if (status == null) {
			return;
		}

		Integer curInteger = transactionRegs.get();
		curInteger--;
		transactionRegs.set(curInteger);
		if (transactionRegs.get() == 0) {
			if (hasInvokeRollback.get())
				saveEdits = false;

			boolean hasError = false;
			try{
				if (saveEdits) {
					getBpmTransaction().commit(status);
				} else {
					getBpmTransaction().rollback(status);
				}
			}catch(Exception e){
				hasError = true;
				e.printStackTrace();
			}finally{
				String tranName = "[" + this.hashCode() + "_"
						+ Thread.currentThread().getId() + "]";
				if (saveEdits) {
					if(hasError){
						logger.info("工作流事务 StopTransactions 事务" + tranName + "提交失败");
					}else{
						logger.info("工作流事务 StopTransactions 事务" + tranName + "提交成功");
					}
				} else {
					if(hasError){
						logger.info("工作流事务 StopTransactions 事务" + tranName + "回滚失败");
					}else{
						logger.info("工作流事务 StopTransactions 事务" + tranName + "回滚成功");
					}
				}
				transactionStatus.remove();
				transactionRegs.remove();
				hasInvokeRollback.remove();
			}
		} else {
			if (!saveEdits)
				hasInvokeRollback.set(true);
		}
	}
	
	/**
	 * 获取事务管理器
	 * @return
	 */
	private static DataSourceTransactionManager getBpmTransaction(){
		DataSourceTransactionManager manager = 
				(DataSourceTransactionManager)SpringBeanFactory.getBean("transactionManager_activiti");
		return manager;
	}
}